/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ClientFrame.java
 *
 * Created on 15-Apr-2009, 1:58:09 PM
 */

package jogs.client;

import jogs.client.games.GameClient;

import java.io.*;
import java.net.*;
import java.util.*;

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

/**
 *
 * @author lanctot
 */
public class ClientFrame extends javax.swing.JFrame
{

  private Socket socket;
  private BufferedReader sin;
  private PrintStream sout;
  private String username;

  /** Creates new form ClientFrame */
  public ClientFrame() 
  {
    initComponents();
    lobbyListModel = new DefaultListModel();
    statusList.setModel(lobbyListModel);
    tabs = new Hashtable<TabInfo, TabThread>();
    //tabThreads = new ArrayList<TabThread>();
  }

  public ClientFrame(Socket _s, BufferedReader _in, PrintStream _out, String _username) 
  {
    socket = _s; sin = _in; sout = _out; username = _username;
    tabs = new Hashtable<TabInfo, TabThread>();
    //tabThreads = new ArrayList<TabThread>();
    initComponents();
    lobbyListModel = new DefaultListModel();
    statusList.setModel(lobbyListModel);
  }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    backPanel = new javax.swing.JPanel();
    horizSplitPane = new javax.swing.JSplitPane();
    backMainPanel = new javax.swing.JPanel();
    vertSplitPane = new javax.swing.JSplitPane();
    mainPanel = new javax.swing.JPanel();
    tabbedPane = new javax.swing.JTabbedPane();
    lobbyTabPanel = new javax.swing.JPanel();
    lobbyTabScrollPane = new javax.swing.JScrollPane();
    lobbyTabTextPane = new javax.swing.JTextPane();
    jPanel5 = new javax.swing.JPanel();
    commandPanel = new javax.swing.JPanel();
    commandScrollPane = new javax.swing.JScrollPane();
    commandTextArea = new javax.swing.JTextArea();
    statusPanel = new javax.swing.JPanel();
    jScrollPane1 = new javax.swing.JScrollPane();
    statusList = new javax.swing.JList();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    backPanel.setBackground(new java.awt.Color(252, 235, 217));

    horizSplitPane.setDividerLocation(850);

    vertSplitPane.setDividerLocation(680);
    vertSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);

    tabbedPane.setBackground(new java.awt.Color(254, 254, 254));

    lobbyTabTextPane.setBackground(new java.awt.Color(254, 254, 254));
    lobbyTabScrollPane.setViewportView(lobbyTabTextPane);

    org.jdesktop.layout.GroupLayout lobbyTabPanelLayout = new org.jdesktop.layout.GroupLayout(lobbyTabPanel);
    lobbyTabPanel.setLayout(lobbyTabPanelLayout);
    lobbyTabPanelLayout.setHorizontalGroup(
      lobbyTabPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(lobbyTabScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 842, Short.MAX_VALUE)
    );
    lobbyTabPanelLayout.setVerticalGroup(
      lobbyTabPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(lobbyTabScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 654, Short.MAX_VALUE)
    );

    tabbedPane.addTab("tab1", lobbyTabPanel);

    org.jdesktop.layout.GroupLayout mainPanelLayout = new org.jdesktop.layout.GroupLayout(mainPanel);
    mainPanel.setLayout(mainPanelLayout);
    mainPanelLayout.setHorizontalGroup(
      mainPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(tabbedPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 847, Short.MAX_VALUE)
    );
    mainPanelLayout.setVerticalGroup(
      mainPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(tabbedPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 679, Short.MAX_VALUE)
    );

    tabbedPane.getAccessibleContext().setAccessibleName("Lobby");

    vertSplitPane.setTopComponent(mainPanel);

    org.jdesktop.layout.GroupLayout jPanel5Layout = new org.jdesktop.layout.GroupLayout(jPanel5);
    jPanel5.setLayout(jPanel5Layout);
    jPanel5Layout.setHorizontalGroup(
      jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(0, 0, Short.MAX_VALUE)
    );
    jPanel5Layout.setVerticalGroup(
      jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(0, 0, Short.MAX_VALUE)
    );

    vertSplitPane.setRightComponent(jPanel5);

    commandTextArea.setColumns(20);
    commandTextArea.setRows(2);
    commandTextArea.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyReleased(java.awt.event.KeyEvent evt) {
        commandTextAreaKeyReleased(evt);
      }
    });
    commandScrollPane.setViewportView(commandTextArea);

    org.jdesktop.layout.GroupLayout commandPanelLayout = new org.jdesktop.layout.GroupLayout(commandPanel);
    commandPanel.setLayout(commandPanelLayout);
    commandPanelLayout.setHorizontalGroup(
      commandPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(commandScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 847, Short.MAX_VALUE)
    );
    commandPanelLayout.setVerticalGroup(
      commandPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(commandPanelLayout.createSequentialGroup()
        .add(commandScrollPane, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 39, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    vertSplitPane.setRightComponent(commandPanel);

    org.jdesktop.layout.GroupLayout backMainPanelLayout = new org.jdesktop.layout.GroupLayout(backMainPanel);
    backMainPanel.setLayout(backMainPanelLayout);
    backMainPanelLayout.setHorizontalGroup(
      backMainPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(vertSplitPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 849, Short.MAX_VALUE)
    );
    backMainPanelLayout.setVerticalGroup(
      backMainPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(vertSplitPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 724, Short.MAX_VALUE)
    );

    horizSplitPane.setLeftComponent(backMainPanel);

    statusList.setModel(new javax.swing.AbstractListModel() {
      String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
      public int getSize() { return strings.length; }
      public Object getElementAt(int i) { return strings[i]; }
    });
    jScrollPane1.setViewportView(statusList);

    org.jdesktop.layout.GroupLayout statusPanelLayout = new org.jdesktop.layout.GroupLayout(statusPanel);
    statusPanel.setLayout(statusPanelLayout);
    statusPanelLayout.setHorizontalGroup(
      statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(0, 120, Short.MAX_VALUE)
      .add(statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
        .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE))
    );
    statusPanelLayout.setVerticalGroup(
      statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(0, 724, Short.MAX_VALUE)
      .add(statusPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
        .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 724, Short.MAX_VALUE))
    );

    horizSplitPane.setRightComponent(statusPanel);

    org.jdesktop.layout.GroupLayout backPanelLayout = new org.jdesktop.layout.GroupLayout(backPanel);
    backPanel.setLayout(backPanelLayout);
    backPanelLayout.setHorizontalGroup(
      backPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(backPanelLayout.createSequentialGroup()
        .addContainerGap()
        .add(horizSplitPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 976, Short.MAX_VALUE)
        .addContainerGap())
    );
    backPanelLayout.setVerticalGroup(
      backPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(backPanelLayout.createSequentialGroup()
        .addContainerGap()
        .add(horizSplitPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 726, Short.MAX_VALUE)
        .addContainerGap())
    );

    org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(backPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(backPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );

    pack();
  }// </editor-fold>//GEN-END:initComponents

    private void commandTextAreaKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_commandTextAreaKeyReleased
      // TODO add your handling code here:
        if (evt.getKeyCode() == KeyEvent.VK_ENTER)
        {
          String command = (commandTextArea.getText()).trim();
          commandTextArea.setText("");

          int tindex = tabbedPane.getSelectedIndex();
          if (tindex == 0) { // lobby tab special case
            sout.println(command);
            return;
          }
          String title = tabbedPane.getTitleAt(tindex);
          // Find the right tab to send command to the right server

          for (TabInfo tt : tabs.keySet())
          {
          	//int i = tt.getIndex();
          	//System.out.println("thread index " + i + " and tindex " + tindex);
            if (tt.getName().equals(title))
            {
              tabs.get(tt).sendCommand(command);
              return;
            }
          }
        }
    }//GEN-LAST:event_commandTextAreaKeyReleased

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ClientFrame().setVisible(true);
            }
        });
    }

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JPanel backMainPanel;
  private javax.swing.JPanel backPanel;
  private javax.swing.JPanel commandPanel;
  private javax.swing.JScrollPane commandScrollPane;
  private javax.swing.JTextArea commandTextArea;
  private javax.swing.JSplitPane horizSplitPane;
  private javax.swing.JPanel jPanel5;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JPanel lobbyTabPanel;
  private javax.swing.JScrollPane lobbyTabScrollPane;
  private javax.swing.JTextPane lobbyTabTextPane;
  private javax.swing.JPanel mainPanel;
  private javax.swing.JList statusList;
  private javax.swing.JPanel statusPanel;
  private javax.swing.JTabbedPane tabbedPane;
  private javax.swing.JSplitPane vertSplitPane;
  // End of variables declaration//GEN-END:variables


  int nextTabIndex = 1;
  Hashtable<TabInfo, TabThread> tabs;
  //ArrayList<TabThread> tabThreads;
  DefaultListModel lobbyListModel;

  private boolean connected;
   /* public class TabInfo
    {
      int index;

      JPanel backPanel;
      JScrollPane backScrollPane;
      JTextPane textPane;

      Socket socket;
      BufferedReader in;
      PrintStream out;

      public TabInfo(JPanel _backPanel, JScrollPane _backPane, JTextPane _textPane,
                     Socket _socket, BufferedReader _in, PrintStream _out,
                     int _index)
      {
        backPanel = _backPanel;
        backScrollPane = _backPane;
        textPane = _textPane;
        socket = _socket; in = _in; out = _out;
        index = _index;
      }
    }*/

   /* public class TabThread extends Thread
    {
      TabInfo tabInfo;
      public TabThread(TabInfo _tabInfo)
      {
        tabInfo = _tabInfo;
      }

      public void run()
      {
        try
        {
          tabInfo.textPane.setText("");

          String line = "";

          while (line != null)
          {
            line = tabInfo.in.readLine();
            append(tabInfo.textPane, line + "\n", "regular");
          }
        }
        catch(Exception e)
        {
          e.printStackTrace();
        }
      }
    }*/

    public String getUsername() { return username; }

    public class StatusUpdateThread extends Thread
    {
      ClientFrame cf; java.util.Timer timer;

      public class StatusUpdateTask extends TimerTask
      {
        ClientFrame cf;
        StatusUpdateThread sut;
        public StatusUpdateTask(ClientFrame _cf, StatusUpdateThread _sut) { cf = _cf; sut = _sut; }
        public void run()
        { cf.sendUpdateRoomInfo(); cf.sendUpdateUserList(); sut.run(); }
      }

      public StatusUpdateThread(ClientFrame _cf)
      { cf = _cf; timer = new java.util.Timer(); }

      public void run()
      {
        System.out.println("Queueing status update requests..");
        timer.schedule(new StatusUpdateTask(cf, this), 10000);
      }
    }

    // type: 0 undetermined, 1 = room, 2 = table
    public void spawnTabThread(String name, String host, int port, String keypass, int type)
    {
      System.out.println("Spawning a tab thread.. to " + name + " " + host
                         + ":" + port + " using " + keypass + " type = " + type);
      
      try
      {
        Socket socket = new Socket(host, port);
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintStream out = new PrintStream(socket.getOutputStream());

        String line = in.readLine(); // AUTHENTICATE
        out.println(username);
        out.println(keypass);

        line = in.readLine();
        //System.out.println("SpawnTab: " + line);

        if (type == 2 && !line.equals("LOGINSUCC"))
        {
          System.out.println("Login to room server failed. Received: " + line); 
          return;
        }

        if (type == 3 && !line.equals("@LOGINSUCC:"))
        {
          System.out.println("Login to table server failed. Received: " + line);
          return;
        }


        // GUI stuff

        JPanel newBackPanel = new JPanel();
        //backPanel.setPreferredSize(new Dimension(634,479));
        JScrollPane newBackPane = new JScrollPane();
        //backPane.setPreferredSize(new Dimension(634,479));
        JTextPane newTextPane = new JTextPane();
        //textArea.setPreferredSize(new Dimension(634,479));
        //textArea.setBackground(Color.WHITE);

        // Give is some styles
        StyledDocument doc = newTextPane.getStyledDocument();

        Style def = StyleContext.getDefaultStyleContext().
                        getStyle(StyleContext.DEFAULT_STYLE);

        Style regular = doc.addStyle("regular", def);
        StyleConstants.setFontFamily(def, "DejaVu Sans");
        StyleConstants.setFontSize(def, 13);
        StyleConstants.setForeground(def, Color.BLACK);

        Style s = doc.addStyle("error", regular);
        StyleConstants.setFontFamily(s, "DejaVu Sans");
        StyleConstants.setFontSize(s, 13);
        StyleConstants.setItalic(s, true);
        StyleConstants.setForeground(s, Color.RED);

        newBackPanel.setBackground(new java.awt.Color(254, 254, 254));

        newTextPane.setBackground(new java.awt.Color(254, 254, 254));
        newTextPane.setRequestFocusEnabled(false);
        newBackPane.setViewportView(newTextPane);

        org.jdesktop.layout.GroupLayout newTabPanelLayout = new org.jdesktop.layout.GroupLayout(newBackPanel);
        newBackPanel.setLayout(newTabPanelLayout);
        newTabPanelLayout.setHorizontalGroup(
          newTabPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(newBackPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 838, Short.MAX_VALUE)
        );
        newTabPanelLayout.setVerticalGroup(
          newTabPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(newBackPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 637, Short.MAX_VALUE)
        );
        
        TabInfo ti = new TabInfo(newBackPanel, newBackPane, newTextPane, socket, in, out, this, type, name, nextTabIndex);
                
        tabbedPane.addTab(name, ti, newBackPanel);

        tabbedPane.setSelectedIndex(tabbedPane.indexOfTab(name));
        commandTextArea.requestFocus();

        newBackPanel.setVisible(true);
        newBackPane.setVisible(true);
        newTextPane.setVisible(true);

        //tabs.add(ti);

        TabThread tt = new TabThread(ti);
        //tabThreads.add(tt);
        tabs.put(ti, tt);
        tt.start();
        statusList.setModel(ti.getListModel());
        nextTabIndex++;
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }
    }

    public void createGame(String type, int tabIndex)
    {
      System.out.println("ClientFrame: creating the game...");
      // get a new panel, now replace the
      JPanel panel = GameClient.newGamePanel(type);

      TabInfo ti = null;//tabs.get(tabIndex);
      for(TabInfo tab: tabs.keySet())
      {
      	if(tab.getIndex() == tabIndex)
      	{
      		ti = tab;
      		break;
      	}
      }
      ti.newGamePanel(panel);

      tabbedPane.removeTabAt(tabIndex);

      // title should be game name
      tabbedPane.insertTab(type, null, panel, "" /*tooltip*/, tabIndex);

      tabbedPane.setSelectedIndex(tabIndex);
    }

    public void closeTab(TabInfo ti)
    {
    	tabbedPane.remove(getTabIndex(ti));
    	tabs.remove(ti);
    	
    }
    
    public int getTabIndex(String pane)
    {
    	int i = this.tabbedPane.indexOfTab(pane);
    	//System.out.println("Index is" + i);
    	return i;
    }
    
    public int getTabIndex(Icon icon)
    {
    	return tabbedPane.indexOfTab(icon);
    }
    
    public void tabbChangedEvent(int index)
    {
    	int i = 0;
    	if(index == 0)
    	{
    		statusList.setModel(lobbyListModel);
    		return;
    	}
    	for(TabInfo tab : tabs.keySet())
    	{
    		i = tab.getIndex();
    		//System.out.println(i);
    		if(i == index)	
    		{
    			//System.out.println("here " + i);
    			statusList.setModel(tab.getListModel());
    			return;
    		}
    	}
    }
    
    public void sendUpdateRoomInfo()
    {
      try
      {
        sout.println("#UPDATE_ROOM_INFO");
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }
    }

    public void sendUpdateUserList()
    {
      try
      {
        sout.println("#UPDATE_USER_LIST");
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }
    }

    String[] roomText;
    String[] userListText;

    public void refreshStatus()
    {
      lobbyListModel = new DefaultListModel();
      statusList.setModel(lobbyListModel);

      // Deja Vu Sans 13 plain
      //Font roomFont = new Font("DejaVu Sans", Font.PLAIN, 13);

      //statusTextPane.setText("");
      //append(statusTextPane, "Legend:\n", "regular");
      //append(statusTextPane, "  Room ", "room");
      //append(statusTextPane, "Game ", "game");
      //append(statusTextPane, "Users ", "regular");
      //append(statusTextPane, "\n\n", "regular");

      if(roomText != null)
      {
      	for(String r : roomText)
      	{
      		lobbyListModel.addElement(new ListObject(r, 0, sout));
      	}
      }
      
      if(userListText != null)
      {
      	for(String u : userListText)
      	{
      		lobbyListModel.addElement(new ListObject(u, 1, sout));
      	}
      }
      
      //lobbyListModel.addElement(roomText);
      //lobbyListModel.addElement(userListText);
      //append(statusTextPane, roomText, "room");
      //append(statusTextPane, userListText, "regular");
    }

    public void append(JTextPane pane, String text, String style)
    {
      try
      {
        StyledDocument doc = pane.getStyledDocument();
        doc.insertString(doc.getLength(), text + "\n", doc.getStyle(style));
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }
    }

    private void handleUpdateRoomInfo(String roominfo)
    {
      try
      {
        // Rooms

        roomText = roominfo.split("###");;

        //String[] roomparts = roominfo.split("###");
        /*for (String roompart : roomparts)
        {
          String[] infoparts = roompart.split(",");
          String name = infoparts[0];
          int clientCount = Integer.parseInt(infoparts[1]);

          roomText += (name + "(" + clientCount + ")\n");
        }*/

        refreshStatus();
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }
    }

    private void handleRoomCount(String roomCount)
    {
    	String[] temp = roomCount.split(",");
    	for (int i=0;i<lobbyListModel.getSize(); i++)
    	{
    		String room = lobbyListModel.get(i).toString();
    		if(room.startsWith(temp[0]))
    		{
    			lobbyListModel.set(i, new ListObject(temp[0] + " (" + temp[1] + ")", 0, sout));
    			return;
    		}
    	}
    }
    
    private void handleUpdateUserList(String userlist)
    {
      try
      {
        // Rooms

        userListText = userlist.split(",");;

        /*String[] parts = userlist.split(",");
        for (String user : parts)
        {
          userListText += (user + "\n");
        }*/

        refreshStatus();
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }
    }

    private void handleNewUser(String user)
    {
    	append(lobbyTabTextPane, user + " has entered the lobby.", "regular");
    	lobbyListModel.addElement(new ListObject(user, 1, sout));
    }
    
    private void handleUserDisconnect(String user)
    {
    	append(lobbyTabTextPane, user + " has left the lobby.", "regular");
    	lobbyListModel.removeElement(user);
    }
    
    // Handles incoming network messages (lobby)
    public boolean handle(String line)
    {
    	if(line == null)
    		return true;
    	String details = null;
  		String command = null;
  	
  		
  		//all commands start with a @ and end with a : 
  		int begin = line.indexOf('@');
  		int end = line.indexOf(':');
  		
  		//if @ and : are not in message than it is not a command
  		if(begin == -1 || end == -1)
  		{
  			//this.send("@ERROR:Not a valid command");
  			return false;
  		}
  		
  		//get the command out of the message
  		command = line.substring(begin, end);
  		
  		//if command has details
  		if(line.length() > end+1)
  			details = line.substring(end+1);
  		//System.out.println("command: " + command);
  		//System.out.println("details: " + details);
  		//System.out.println(command.equals("@NEWUSER"));
      if (command.equals("@OKJOIN"))
      {
        // Comes in as @OKJOIN:<room> <host> <port> <keypass>
        String[] parts = details.split(",");

        String room = parts[0];
        String host = parts[1];
        int port = Integer.parseInt(parts[2]);
        String keypass = parts[3];

        System.out.println("Got OKJOIN details = " + details);

        spawnTabThread(room, host, port, keypass, 2);
        //System.out.println(host);
        //System.out.println(port);
        //System.out.println(keypass);
      }
      else if (command.equals("@OKSIT"))
      {
        System.out.println("Handling OKSIT..");
        
        // Comes in as @OKSIT:<table> <host> <port> <keypass>
        String[] parts = details.split(" ");

        String table = parts[0];
        String host = parts[1];
        int port = Integer.parseInt(parts[2]);
        String keypass = parts[3];

        spawnTabThread(table, host, port, keypass, 3);
        //System.out.println(host);
        //System.out.println(port);
        //System.out.println(keypass);
      }
      else if (command.equals("@OKROOMINFO"))
        handleUpdateRoomInfo(details);
      else if (command.equals("@OKUSERLIST"))
        handleUpdateUserList(details);
      else if (command.equals("@NEWUSER"))
      	handleNewUser(details);
      else if (command.equals("OKDISCONNECT"))
      		connected = false;
      else if (command.equals("@DISCONNECTED"))
      	handleUserDisconnect(details);
      else if (command.equals("@ROOMCOUNT"))
      	handleRoomCount(details);
      else
        return false;

      return true;
    }

    public void disconnect()
    {
    	this.sout.println("@DISC:");
    	for(TabInfo taby :tabs.keySet())
    		taby.disconnect();
    }
    
    public void setupGUI()
    {
      commandTextArea.requestFocus();
      String lobbytext = "";

      backPanel.setVisible(true);
      commandPanel.setVisible(true);
      commandTextArea.setVisible(true);
      horizSplitPane.setVisible(true);
      lobbyTabScrollPane.setVisible(true);
      lobbyTabTextPane.setVisible(true);
      mainPanel.setVisible(true);
      statusPanel.setVisible(true);
      tabbedPane.setVisible(true);
      vertSplitPane.setVisible(true);

      lobbyTabTextPane.setRequestFocusEnabled(false);
      statusList.setRequestFocusEnabled(false);
      
      TabInfo ti = new TabInfo(backPanel, lobbyTabScrollPane, lobbyTabTextPane, 
                               socket, sin, sout, this, 1, "Lobby", 0);
      tabs.put(ti,new TabThread(ti));

      tabbedPane.setName("Lobby");
      tabbedPane.setTitleAt(0, "Lobby");
      tabbedPane.setIconAt(0, ti);
      this.tabbedPane.addChangeListener(new jogs.client.listeners.TabChangeListener(this));
      
      this.statusList.setCellRenderer(new ListRenderer());
      
      this.addWindowListener(new jogs.client.listeners.ClientFrameListener());
      statusList.addMouseListener(new jogs.client.listeners.ListMouseListener(statusList, username));      
      //Initialize some styles (statusTextPane)
      /*StyledDocument doc = statusTextPane.getStyledDocument();

      Style def = StyleContext.getDefaultStyleContext().
                      getStyle(StyleContext.DEFAULT_STYLE);

      //Style regular = doc.addStyle("regular", def);
      StyleConstants.setFontFamily(def, "DejaVu Sans");
      StyleConstants.setFontSize(def, 13);
      StyleConstants.setForeground(def, Color.BLACK);

      Style s = doc.addStyle("room", regular);
      StyleConstants.setFontFamily(s, "DejaVu Sans");
      StyleConstants.setFontSize(s, 13);
      StyleConstants.setBold(s, true);
      StyleConstants.setForeground(s, new Color(0, 0, 200));

      s = doc.addStyle("game", regular);
      StyleConstants.setFontFamily(s, "DejaVu Sans");
      StyleConstants.setFontSize(s, 13);
      StyleConstants.setBold(s, true);
      StyleConstants.setForeground(s, new Color(0, 150, 0));

      //Initialize some styles (lobbyTextPane
      doc = lobbyTabTextPane.getStyledDocument();

      def = StyleContext.getDefaultStyleContext().
                      getStyle(StyleContext.DEFAULT_STYLE);

      regular = doc.addStyle("regular", def);
      StyleConstants.setFontFamily(def, "DejaVu Sans");
      StyleConstants.setFontSize(def, 13);
      StyleConstants.setForeground(def, Color.BLACK);*/

    }
    
    
    public TabInfo getTabInfo(int index)
    {
    	try
    	{
    		return (TabInfo)tabbedPane.getIconAt(index);
    	}
    	catch(Exception e)
    	{
    		return null;
    	}
    		
    	/*TabInfo r = null;
    	for (TabInfo tab : tabs.keySet())
    	{
    		if(tab.getIndex() == index)
    		{
    			r = tab;
    			break;
    		}
    	}
    	return r;*/
    }

    public void clientLoop()
    {
      setTitle("The Gamer's Guild Client - " + username);

      setupGUI();

      sendUpdateRoomInfo();
      sendUpdateUserList();

      try
      {
        Thread.sleep(10);

        // Server should send us the updates
        //StatusUpdateThread sut = new StatusUpdateThread(this);
        ///sut.start();
        connected = true;
        while(connected)
        {
          String line = sin.readLine();

          boolean handled = handle(line);

          if (!handled)
          {
            //lobbytext += (line + "\n");

            int selected = tabbedPane.getSelectedIndex();
            //TabInfo ti = tabs.get(selected);

            JTextPane pane = null;
            if (selected == 0)
              pane = lobbyTabTextPane;
            else
              pane = getTabInfo(selected).textPane;

            append(pane, line, "regular");
            //append(pane, "\n", "regular");
          }

        }
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }

    }

}
